using System;
using NUnit.Framework;



namespace tdd.dbupd
{
    // data

    public class A
    {
        public int ballance { get; set; }
        public string name { get; set;}
    }

    // method less roles

    public interface IAccount
    {
        int ballance { get; set; }
        string name { get; set; }
    }

    public interface IDestAccount : IAccount { }
    public interface ISourceAccount : IAccount { }

    // role mapp + method full roles

    public class Account: A, ISourceAccount, IDestAccount{}

    public static class AA
    {
        public static void Decrement(this ISourceAccount s, int x)
        {
            s.ballance--;
            Console.WriteLine("dec {1} : {0}", x, s.name);
        }

        public static void Increment(this IDestAccount s, int x)
        {
            s.ballance++;
            Console.WriteLine("inc {1}: {0}", x, s.name);
        }
    }

    // context

    public class Context
    {
        private int am;
        private ISourceAccount sa;
        private IDestAccount da;

        public Context(ISourceAccount sa_, IDestAccount da_, int am_)
        {
            am = am_;
            sa = sa_;
            da = da_;
        }

        public void Execute()
        {
            @sa.Transfer(@da, @am);
        }
    }

    // interaction

    internal static class Source
    {
        internal static void Transfer(this ISourceAccount @s, IDestAccount @d, int a)
        {
            @s.Decrement(a);
            @d.Increment(a);
        }
    }

    [TestFixture]
    public class Test
    {
        [Test]
        public void TEST_MULTIPLE_DISPATCH()
        {
            
            var a1 = new Account() {name="a",ballance = 100};
            
            var a2 = new Account() {name="b",ballance = 300};

            new Context(a1, a2, 30).Execute();
            
            new Context(a2, a1, 50).Execute();

        }
    }
}